package com.example.rabbitmqboot.controller;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author cxu
 * @version 1.0.0
 * @description 消息发送控制类
 * @date 2021年09月21日 21:51:00
 */
@RestController
@RequestMapping("/mq")
public class RabbitMessageController {

    private RabbitTemplate rabbitTemplate;
    @Autowired
    public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
        // 定义confirm回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * 参数说明：
             * correlationData：配置信息，在发送消息时设置的
             * ack：交换机是否成功收到消息，true为收到，false为没收到
             * cause: 错误原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("我是回调函数");
                if(ack){
                    System.out.println("消息成功放入exchange");
                }else{
                    System.out.println("消息发送失败：" + cause);
                    // 重新发送。。。。
                }
            }
        });

        //定义return回调函数
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback(){
            // 该方法执行就代表未成功放入queue
            /**
             * 参数说明
             * returnedMessage：消息放入失败时，信息集合实体类，里面包含：
             *     message：发送的消息对象
             *     replyCode：错误码
             *     replyText：错误信息
             *     exchange：交换机
             *     proutingKey：路由key
             */
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                System.out.println("消息放入失败");
                System.out.println("原因：" + returnedMessage.getReplyCode() + "-" + returnedMessage.getReplyText());
            }
        });
        //设置交换机处理失败消息的模式，失败时执行回调
        rabbitTemplate.setMandatory(true);
    }
    
    @RequestMapping("/send")
    @ResponseBody
    public String sendMessage(@RequestParam("message") String message, @RequestParam("routing") String routing) {
        Message messageBody = new Message(message.getBytes());
        rabbitTemplate.convertAndSend("topic_exchange", routing, messageBody);
        System.out.println(rabbitTemplate.isMandatoryFor(messageBody));
        return "发送成功";
    }
}
